#include <iostream>
#include <cstdio>
#include <string>
#include <pthread.h>
#include <unistd.h>

using namespace std;

// 线程退出
void *threadRoutine(void *args)
{

    // 新线程先运行10s
    for(int i=0;i<10;i++)
    {
        std::cout<<(char*)args<<" : "<<i<<std::endl;
        sleep(1);
    }

    // 方案二: 要退出的线程自己调用pthread_exit
    //void pthread_exit(void *retval);
    // void *retval : 与回调函数threadRoutine的返回值意义一样

    cout<<"线程退出"<<endl;
    pthread_exit((void*)3);

    // 方案一: 回调函数return
    // 返回数字3
    //return (void*)3;
}

int main()
{
    // 1.先创建一个新线程
    pthread_t tid;

    pthread_create(&tid,nullptr,threadRoutine,(void*)"new thread");

    // 先让新线程运行5s
    sleep(5);
    // 方案三: 通过pthread_cancel来取消某线程
    // int pthread_cancel(pthread_t thread);
    // pthread_t thread : 要取消某线程的线程id
    pthread_cancel(tid);
    cout<<"线程取消成功"<<endl;

    // 2.等待线程退出
    void *retval;
    pthread_join(tid,&retval); // 线程被取消，join的时候，退出码是-1 #define PTHREAD_CANCELED ((void *) -1)

    // 3.等待成功,主线程再跑5s
    std::cout<<" retval: "<<retval<<std::endl;
    sleep(5);

    return 0;
}

// // 线程等待---了解回调函数的传参与返回
// void *threadRoutine(void *args)
// {

//     // 新线程先运行5s
//     for(int i=0;i<5;i++)
//     {
//         std::cout<<(char*)args<<" : "<<i<<std::endl;
//         sleep(1);
//     }

//     // 返回数字3
//     return (void*)3;
// }

// int main()
// {
//     // int pthread_join(pthread_t thread, void **retval);
//     // pthread_t thread : 需要等待线程的id
//     // void **retval : 输出型参数,输出的类型是void*,所以需要传void**来改变外面的void*(也即通过void*的地址来改变void*)

//     // 1.先创建一个新线程
//     pthread_t tid;

//     pthread_create(&tid,nullptr,threadRoutine,(void*)"new thread");

//     // 2.等待线程退出
//     void *retval;
//     pthread_join(tid,&retval); // 只能阻塞式等待 

//     // 3.等待成功,主线程再跑5s
//     std::cout<<"等待成功 retval: "<<retval<<std::endl;
//     int count=0;
//     while(true)
//     {
//         if(count++ !=5)
//         {
//             std::cout<<"main thread\n";
//             sleep(1);
//         }
//         else
//         {
//             break;
//         }
//     }

//     return 0;
// }

// // 线程创建
// void *threadRoutine(void *args)
// {
//     const string name = (char *)args;
//     while(true)
//     {
//         //cout<<(char *)args<<endl;
//         cout<<name<<endl;
//         sleep(1);
//     }

//     return nullptr;
// }
// 
// int main()
// {
//     // 创建一个新线程
//     //int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
//     // pthread_t *thread : 输出型参数,返回线程LWP
//     // const pthread_attr_t *attr : 现在默认传nullptr
//     // void *(*start_routine) : 函数指针,该函数的返回值为void*,参数也为void*.当新线程创建成功时通过回调,该新线程就在该函数中开始执行
//     // void *arg : 回调函数要传参的值

//     // 尝试创建5个线程

//     pthread_t tids[5];
//     char buff[32];
//     for(int i=0;i<sizeof(tids)/sizeof(tids[0]);i++)
//     {
//         //char buff[32];

//         // 将数据格式化写到字符串中
//         snprintf(buff,sizeof buff,"new thread: %d",i);

//         pthread_create(tids+i,nullptr,threadRoutine,(void*)buff);

//         // 创建一个新线程后等待1s
//         sleep(1);
//     }

//     // 主线程的任务...
//     while(true)
//     {
//         for(int i=0;i<sizeof(tids);i++)
//         {
//             std::cout<<" main thread "<<tids[i]<<std::endl;
//             sleep(1);
//         }
//     }

//     return 0;
// }

// // pthread_t 多大
// int main()
// {
//     // 8字节
//     std::cout<<sizeof(pthread_t)<<std::endl;

//     for(int i=0;i<sizeof(pthread_t);i++)
//     {
//         std::cout<<i<<endl;
//     }

//     return 0;
// }